package manage.service;

import m.common.model.util.*;
import m.common.service.Service;
import m.system.cache.CacheUtil;
import m.system.db.TransactionManager;
import m.system.exception.MException;
import m.system.lang.PageInfo;
import m.system.util.ArrayUtil;
import m.system.util.DateUtil;
import m.system.util.GenerateID;
import m.system.util.StringUtil;
import manage.dao.AdminLoginDao;
import manage.model.*;
import manage.util.DictionaryUtil;

import java.sql.SQLException;
import java.util.*;

public class AdminLoginService extends Service {
	private final Map<String,Date> errorDate= new HashMap<>();
	private final Map<String,Integer> errorNum= new HashMap<>();
	private void errorVerify(String username) throws MException{
		Date date=errorDate.get(username);
		Integer num=errorNum.get(username);
		if(null==date||DateUtil.add(date, Calendar.HOUR_OF_DAY, 1).getTime()<new Date().getTime()){
			errorDate.put(username, new Date());
			errorNum.put(username, 1);
		}else if(null!=num&&num<10){
			errorNum.put(username, num+1);
		}else{
			throw new MException(this.getClass(),"操作频繁,请稍后再试.");
		}
	}
	public AdminLogin loginVerification(AdminLogin model) throws Exception{
		if(StringUtil.isSpace(model.getUsername())){
			throw new MException(this.getClass(),"账号不能为空!");
		}else if(StringUtil.isSpace(model.getPassword())){
			throw new MException(this.getClass(),"密码不能为空!");
		}else{
			String user_oid=getDao(AdminLoginDao.class).getUserOid(model.getUsername(),model.getPassword());
			if(StringUtil.isSpace(user_oid)){
				errorVerify(model.getUsername());
				throw new MException(this.getClass(),"账号或者密码错误!");
			}else{
				model=CacheUtil.get(AdminLogin.class,user_oid);
				if("9".equals(model.getStatus())){
					throw new MException(this.getClass(),"账号已被停用!");
				}
				model.setToken(UUID.randomUUID().toString());
				ModelUpdateUtil.updateModel(model, "token");
				return model;
			}
		}
	}
	/**
	 * 保存
	 *  model
	 *  password
	 * 
	 *  Exception
	 */
	public String save(AdminLogin model, String password) throws Exception {
		return save(model,null,password,false);
	}
	/**
	 * 保存并关联到用户组
	 *  model
	 *  link 只有新增才关联
	 *  password
	 * 
	 *  Exception
	 */
	public String save(AdminLogin model,AdminGroupLink link, String password,Boolean useKey) throws Exception {
		ModelCheckUtil.checkNotNull(model,"username","userNo","realname");
		if(!StringUtil.noSpace(password).equals(StringUtil.noSpace(model.getPassword()))){
			throw new MException(this.getClass(),"两次输入的密码不一致");
		}
		ModelCheckUtil.checkUniqueCombine(model, new String[]{"username"});
		if(null!=model.getUserNo()) {
			ModelCheckUtil.checkUniqueCombine(model, new String[]{"userNo"});
		}
		String msg;
		TransactionManager tm=new TransactionManager();
		try{
			tm.begin();
			if(StringUtil.isSpace(model.getOid())){
				if(null!=useKey&&useKey){
					model.setOid(model.getUserNo());
				}else {
					model.setOid(GenerateID.generatePrimaryKey());
				}
				model.setCreateDate(new Date());
				model.setStatus(StatusModel.Status_Enable);
				model.setPassword(StringUtil.toMD5(model.getPassword()));
				ModelUpdateUtil.insertModel(model);
				if(null!=link&&null!=link.getAdminGroup()&&!StringUtil.isSpace(link.getAdminGroup().getOid())) {
					link.setAdminGroup(ModelQueryList.getModel(link.getAdminGroup(), "oid"));
					if(null!=link.getAdminGroup()) {
						link.setOid(GenerateID.generatePrimaryKey());
						link.setAdmin(model);
						ModelUpdateUtil.insertModel(link);
					}else {
						throw new MException(this.getClass(), "需要关联的组不存在");
					}
				}
				msg="保存成功";
			}else{
				if(model.getOid().equals("1")&&!model.getAdminGroup().getOid().equals("1")){
					throw new MException(this.getClass(),"admin帐号不能修改管理员组");
				}
				AdminLogin admin=ModelQueryList.getModel(AdminLogin.class,model.getOid(),"*");
				if(StringUtil.noSpace(admin.getUserNo()).equals(model.getOid())){
					model.setUserNo(admin.getOid());
				}
				if(StringUtil.isSpace(model.getPassword())){
					ModelUpdateUtil.updateModel(model, "realname","userNo","adminGroup.oid","headImage.oid");
				}else{
					model.setPassword(StringUtil.toMD5(model.getPassword()));
					ModelUpdateUtil.updateModel(model, "realname","userNo","password","adminGroup.oid","headImage.oid");
				}
				msg="修改成功";
			}
			DictionaryUtil.clear(AdminLogin.class);
			CacheUtil.clear(AdminLogin.class);
			CacheUtil.clear(ModuleInfo.class);//清楚模块缓存
			CacheUtil.clear(MenuInfo.class);//清楚菜单缓存
			tm.commit();
		}catch(Exception e){
			tm.rollback();
			throw e;
		}
		return msg;
	}
	/**
	 * 更新最后登录时间和ip
	 *  admin
	 *  ip
	 *  MException
	 */
	public void updateLastInfo(AdminLogin admin,String ip) throws MException{
		admin.setLastLoginTime(new Date());
		admin.setLastLoginIp(ip);
		if(null==admin.getLoginCount()){
			admin.setLoginCount(1);
		}else{
			admin.setLoginCount(admin.getLoginCount()+1);
		}
		ModelUpdateUtil.updateModel(admin, "lastLoginTime","lastLoginIp","loginCount");
	}
	/**
	 * 获取全部管理员
	 *  orgGroup 节点组  空代表全查
	 *  roleGroup 过滤组 空代表全查
	 */
	public PageInfo getAll(QueryPage page, String realname, String orgGroup, String roleGroup) throws SQLException, MException{
		List<QueryCondition> cons= new ArrayList<>();
		if(!StringUtil.isSpace(orgGroup)) {
			if(orgGroup.equals("C")){
				cons.add(QueryCondition.in("oid",
					ModelQueryList.instance(AdminGroupLink.class, new String[]{"admin.oid"}, null,
						QueryCondition.eq("type","C")
					)
				));
			}else{
				String[] nodes=ArrayUtil.toNoEmptyArray(StringUtil.noSpace(orgGroup).split(","));
				List<QueryCondition> qc= new ArrayList<>();
				qc.addAll(QueryCondition.eqs("adminGroup.oid", nodes));
				qc.addAll(QueryCondition.eqs("adminGroup.num", nodes));
				qc.add(
					QueryCondition.in("oid",
						ModelQueryList.instance(AdminGroupLink.class, new String[] {"admin.oid"}, null,
							QueryCondition.or(
								QueryCondition.in("adminGroup.oid", nodes),
								QueryCondition.in("adminGroup.num", nodes),
								QueryCondition.in("adminGroup.parent.oid", nodes),
								QueryCondition.in("adminGroup.parent.num", nodes))
						)
					)
				);
				cons.add(QueryCondition.or(qc.toArray(new QueryCondition[] {})));
			}
		}
		if(!StringUtil.isSpace(roleGroup)) {
			if(roleGroup.equals("B")){
				cons.add(QueryCondition.in("oid",
					ModelQueryList.instance(AdminGroupLink.class, new String[]{"admin.oid"}, null,
						QueryCondition.eq("type","B")
					)
				));
			}else {
				String[] flter = ArrayUtil.toNoEmptyArray(StringUtil.noSpace(roleGroup).split(","));
				List<QueryCondition> qc = new ArrayList<>();
				qc.addAll(QueryCondition.eqs("adminGroup.oid", flter));
				qc.addAll(QueryCondition.eqs("adminGroup.num", flter));
				qc.add(
					QueryCondition.in("oid",
						ModelQueryList.instance(AdminGroupLink.class, new String[]{"admin.oid"}, null,
							QueryCondition.or(
								QueryCondition.in("adminGroup.oid", flter),
								QueryCondition.in("adminGroup.num", flter))
						)
					)
				);
				cons.add(QueryCondition.or(qc.toArray(new QueryCondition[]{})));
			}
		}
		cons.add(QueryCondition.eq("status", "0"));
		if(!StringUtil.isSpace(realname)){
			cons.add(QueryCondition.or(
				QueryCondition.like("realname",realname),
				QueryCondition.like("username",realname)
			));
		}
		return ModelQueryList.getModelPageInfo(ModelQueryList.instance(AdminLogin.class, new String[] {"*","adminGroup.*"},page,
				QueryCondition.and(cons.toArray(new QueryCondition[] {})), QueryOrder.asc("adminGroup.sort")));
	}
}
